#if defined(TSINGMA_MX) || defined(TSINGMA_GX) || defined(ARCTIC)
#if (FEATURE_MODE == 0)
/**
 @file sys_tmm_monitor.c

 @date 2019-5-5

 @version v1.0

 The file contains TMM monitor APIs of sys layer
*/

/***************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"

#include "sys_usw_common.h"
#include "sys_usw_monitor.h"
#include "sys_usw_register.h"
#include "sys_usw_dma.h"
#include "sys_usw_efd.h"
#include "sys_usw_port_api.h"
#include "sys_usw_interrupt.h"
#include "drv_api.h"

#define SYS_MONITOR_TYPE_DLB       0xA8
#define SYS_MONITOR_TYPE_EFD       0xA7
#define SYS_MONITOR_TYPE_LATENCY   0xA6
#define SYS_MONITOR_TYPE_ERM       0xA5
#define SYS_MONITOR_TYPE_IRM       0xA4

#ifdef ARCTIC
extern int32
sys_at_monitor_buf_sync_data(uint8 lchip, void* p_data);
extern int32
sys_at_monitor_latency_sync_data(uint8 lchip, void* p_data);
extern int32
sys_at_monitor_sync_buffer_stats(uint8 lchip, void* p_data);
extern int32
sys_at_monitor_snapshot_state_isr(uint8 lchip, uint32 intr, void* p_data);
#endif
extern int32
_sys_usw_monitor_get_mburst_level(uint8 lchip, uint8 *level, uint64 thrd);
/**
@brief Monitor hash key hook.
*/
uint32
_sys_tmm_monitor_hash_make(sys_monitor_path_config_t* backet)
{
    uint32 val = 0;
    uint8* data = NULL;
    uint8   length = 0;


    if (!backet)
    {
        return 0;
    }

    val = (backet->src_lport << 16) | (backet->dst_lport);

    data = (uint8*)&val;
    length = sizeof(uint32);

    return ctc_hash_caculate(length, data);
}

/**
 @brief Monitor hash comparison hook.
*/
bool
_sys_tmm_monitor_hash_cmp(sys_monitor_path_config_t* p_cfg1,
                                sys_monitor_path_config_t* p_cfg2)
{
    if (!p_cfg1 || !p_cfg2)
    {
        return FALSE;
    }

    if ((p_cfg1->src_lport == p_cfg2->src_lport) &&
        (p_cfg1->dst_lport == p_cfg2->dst_lport))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_tmm_monitor_dump_hash_node(sys_monitor_path_config_t* p_cfg,
                                   uint8* gchip)
{
#ifndef CTC_SHELL_DEBUG_ON
    uint32 src_gport = 0;
    uint32 dst_gport = 0;
    CTC_PTR_VALID_CHECK(p_cfg);
    src_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(*gchip, p_cfg->src_lport);
    dst_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(*gchip, p_cfg->dst_lport);
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "0x%04x        0x%04x\n", src_gport, dst_gport);
#endif
    return 0;
}

STATIC int32
_sys_tmm_monitor_free_node_data(void* node_data, void* user_data)
{
    if (node_data)
    {
        mem_free(node_data);
    }

    return 1;
}

STATIC int32
_sys_tmm_monitor_alloc_viewid(uint8 lchip, uint16 lport, uint8 is_dst,uint8 path_mode, uint32* viewid)
{
    uint8 index = 0;
    uint8 avl_index = 0xFF;
    uint8 port_cnt[CTC_MONITOR_LATENCY_MODE_MAX][2] ={{0,0},{32,64},{0,0},
                                                      {0,0}, {0,0},{32,8},
                                                      {8,32},{16,32},{32,16}};
    uint8 port_cnt_at[CTC_MONITOR_LATENCY_MODE_MAX][2] ={{0,0},{64,64},{0,0},
                                                      {0,0}, {0,0},{32,16},
                                                      {16,32},{32,32},{32,32}};

    sys_monitor_port_t* port_array = p_usw_monitor_master[lchip]->port_array[is_dst];

    /*check exist*/
    for(index = 0; index < (DRV_FROM_AT(lchip) ? port_cnt_at[path_mode][is_dst] : port_cnt[path_mode][is_dst]); index++)
    {
        if (port_array[index].valid == 0)
        {
            avl_index = index;
            break;
        }

        if(port_array[index].lport == lport)
        {
            *viewid = index;
            port_array[index].ref_cnt++;
            return CTC_E_NONE;
        }
    }
    if(avl_index == 0xFF)
    {
       SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "No resouce!\n");
       return CTC_E_NO_RESOURCE;
    }

    /*add new port*/
    sal_memset(&port_array[avl_index], 0, sizeof(sys_monitor_port_t));
    port_array[avl_index].valid = 1;
    port_array[avl_index].lport = lport;
    port_array[avl_index].ref_cnt = 1;
    *viewid = avl_index;

    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_monitor_free_viewid(uint8 lchip, uint16 lport, uint8 is_dst, uint8 path_mode)
{
    uint8 index = 0;
    uint8 find = 0;
    uint8 port_cnt[CTC_MONITOR_LATENCY_MODE_MAX][2] ={{0,0},{32,64},{0,0},
                                                      {0,0}, {0,0},{32,8},
                                                      {8,32},{16,32},{32,16}};
    uint8 port_cnt_at[CTC_MONITOR_LATENCY_MODE_MAX][2] ={{0,0},{64,64},{0,0},
                                                      {0,0}, {0,0},{32,16},
                                                      {16,32},{32,32},{32,32}};
    sys_monitor_port_t* port_array = p_usw_monitor_master[lchip]->port_array[is_dst];


    for (index = 0; index < (DRV_FROM_AT(lchip) ? port_cnt_at[path_mode][is_dst] : port_cnt[path_mode][is_dst]); index++ )
    {
        if ((port_array[index].lport == lport)&&(port_array[index].valid))
        {
            find = 1;
            break;
        }
    }

    if (find)
    {
        port_array[index].ref_cnt--;
        if (port_array[index].ref_cnt == 0)
        {
            port_array[index].valid = 0;
        }
    }
    else
    {
        return CTC_E_NOT_EXIST;
    }

    return CTC_E_NONE;

}

STATIC int32
_sys_tmm_monitor_get_path_latency_ptr(uint8 lchip, void* p_mon_watermark, uint16* mon_ptr)
{
    uint32 cmd = 0;
    uint16 src_lport = 0;
    uint16 dst_lport = 0;
    uint32 src_viewid = 0;
    uint32 dst_viewid = 0;
    uint32 path_mon_mode = 0;
    uint16 queue_id = 0;
    ctc_monitor_watermark_t* p_watermark = (ctc_monitor_watermark_t*)p_mon_watermark;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->src_gport, lchip, src_lport);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_watermark->gport, lchip, dst_lport);

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_pathMonMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &path_mon_mode));

    cmd = DRV_IOR(DsPathViewSrcMap_t, DsPathViewSrcMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, src_lport, cmd, &src_viewid));

    cmd = DRV_IOR(DsPathViewDstMap_t, DsPathViewDstMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dst_lport, cmd, &dst_viewid));

    *mon_ptr = 0xFFFF;
    queue_id = p_watermark->queue.queue_id;


    switch (path_mon_mode)
    {
        case CTC_MONITOR_LATENCY_MODE_1:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (dst_viewid & 0x3F) << 6 | (src_viewid & 0x3F);
            }
            break;

        case CTC_MONITOR_LATENCY_MODE_2:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 11 | dst_lport << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_3:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 11 | src_lport << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_4:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid))
            {
                *mon_ptr = src_lport << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_5:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 11 | (src_viewid & 0x1F) << 6 | (dst_viewid & 0x7) << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_6:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = ((queue_id & 0x8) >> 3) << 11 | (dst_viewid & 0x1F) << 6 | (src_viewid & 0x7) << 3 | (queue_id & 0x7);
            }
            break;
        case CTC_MONITOR_LATENCY_MODE_7:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (dst_viewid & 0x1F) << 7 | (src_viewid & 0xF) << 3 | (queue_id & 0x7);
            }
            break;

        case CTC_MONITOR_LATENCY_MODE_8:
            if (SYS_MONITOR_VIEWID_VALID_CHECK(src_viewid) && SYS_MONITOR_VIEWID_VALID_CHECK(dst_viewid))
            {
                *mon_ptr = (src_viewid & 0x1F) << 7 | (dst_viewid & 0xF) << 3 | (queue_id & 0x7);
            }
            break;

        default:
            break;
    }

    if (0xFFFF == *mon_ptr)
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "monitor ptr = %d\n", *mon_ptr);
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_set_path_latency(uint8 lchip, void* p_cfg, uint8 enable)
{
    int32 ret = CTC_E_NONE;
    uint32 path_mon_mode = 0;
    uint32 cmd = 0;
    uint32 src_viewid = 0;
    uint32 dst_viewid = 0;
    sys_monitor_path_config_t* path_cfg = p_cfg;
    sys_monitor_path_config_t* p_path_cfg = NULL;

    p_path_cfg = ctc_hash_lookup(p_usw_monitor_master[lchip]->p_monitor_hash, path_cfg);

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_pathMonMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &path_mon_mode));

    switch (path_mon_mode)
    {
        case CTC_MONITOR_LATENCY_MODE_1:
        case CTC_MONITOR_LATENCY_MODE_5:
        case CTC_MONITOR_LATENCY_MODE_6:
        case CTC_MONITOR_LATENCY_MODE_7:
        case CTC_MONITOR_LATENCY_MODE_8:

            if (enable)
            {
                if(p_path_cfg != NULL)
                {
                    return CTC_E_EXIST;
                }

                /*new node*/
                p_path_cfg = mem_malloc(MEM_MONITOR_MODULE, sizeof(sys_monitor_path_config_t));
                if (NULL == p_path_cfg)
                {
                    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                    return CTC_E_NO_MEMORY;
                }

                sal_memcpy(p_path_cfg, path_cfg, sizeof(sys_monitor_path_config_t));
                CTC_ERROR_GOTO(_sys_tmm_monitor_alloc_viewid(lchip, p_path_cfg->src_lport, 0, path_mon_mode, &src_viewid), ret, error1);
                CTC_ERROR_GOTO(_sys_tmm_monitor_alloc_viewid(lchip, p_path_cfg->dst_lport, 1, path_mon_mode, &dst_viewid), ret, error2);

                if (NULL == ctc_hash_insert(p_usw_monitor_master[lchip]->p_monitor_hash, p_path_cfg))
                {
                    ret = CTC_E_NO_MEMORY;
                    goto error3;
                }

            }
            else
            {
                if(p_path_cfg == NULL)
                {
                    return CTC_E_NOT_EXIST;
                }

                CTC_ERROR_RETURN(_sys_tmm_monitor_free_viewid(lchip, p_path_cfg->src_lport, 0, path_mon_mode));
                CTC_ERROR_RETURN(_sys_tmm_monitor_free_viewid(lchip, p_path_cfg->dst_lport, 1, path_mon_mode));

                ctc_hash_remove(p_usw_monitor_master[lchip]->p_monitor_hash, p_path_cfg);
                mem_free(p_path_cfg);
            }
            break;

        case CTC_MONITOR_LATENCY_MODE_2:
        case CTC_MONITOR_LATENCY_MODE_3:
        case CTC_MONITOR_LATENCY_MODE_4:
            break;
        default:
            break;
    }

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_PATH_LATENCY, 1);

    src_viewid = enable ? (1 << 6) | src_viewid : 0;
    cmd = DRV_IOW(DsPathViewSrcMap_t, DsPathViewSrcMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, path_cfg->src_lport, cmd, &src_viewid));

    dst_viewid = enable ? (1 << 6) | dst_viewid : 0;
    cmd = DRV_IOW(DsPathViewDstMap_t, DsPathViewDstMap_viewId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, path_cfg->dst_lport, cmd, &dst_viewid));

    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "src_lport=%d, src_viewid = %d, valid = %d, ref_cnt = %d\n",
        path_cfg->src_lport, src_viewid & 0x3F,
        p_usw_monitor_master[lchip]->port_array[0][src_viewid & 0x3F].valid,
        p_usw_monitor_master[lchip]->port_array[0][src_viewid & 0x3F].ref_cnt);
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "dst_lport=%d, dst_viewid = %d, valid = %d, ref_cnt = %d\n",
        path_cfg->dst_lport, dst_viewid & 0x3F,
        p_usw_monitor_master[lchip]->port_array[1][dst_viewid & 0x3F].valid,
        p_usw_monitor_master[lchip]->port_array[1][dst_viewid & 0x3F].ref_cnt);

    return CTC_E_NONE;
error3:
    _sys_tmm_monitor_free_viewid(lchip, p_path_cfg->dst_lport, 1, path_mon_mode);
error2:
    _sys_tmm_monitor_free_viewid(lchip, p_path_cfg->src_lport, 0, path_mon_mode);
error1:
    mem_free(p_path_cfg);
    return ret;
}

int32
sys_tmm_monitor_get_path_latency(uint8 lchip, void* p_cfg, uint8 *enable)
{
    sys_monitor_path_config_t* path_cfg = (sys_monitor_path_config_t*)p_cfg;
    sys_monitor_path_config_t* p_path_cfg = NULL;

    p_path_cfg = ctc_hash_lookup(p_usw_monitor_master[lchip]->p_monitor_hash, path_cfg);
    *enable = p_path_cfg ? 1 : 0;

    return CTC_E_NONE;
}

int32
sys_tmm_monitor_get_path_latency_watermark(uint8 lchip, void* p_mon_watermark, uint16 channel_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint16 mon_ptr = 0;
    uint16 idx1 = 0;
    uint16 idx2 = 0;
    uint8  step = 0;
    ds_t ds;
    ctc_monitor_watermark_t* p_watermark = (ctc_monitor_watermark_t* )p_mon_watermark;

     sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_legacyFeatureEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    if (field_value == 1)/*legacy mode,DsLatencyMon0 for cnt,DsLatencyMon1 for latency*/
    {
        cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmd, &ds));
        p_watermark->u.latency.max_latency = GetDsLatencyMon1(V, u_g1_0_latencyMax_f , &ds) << 5;
        p_watermark->u.latency.min_latency = GetDsLatencyMon1(V, u_g1_0_latencyMin_f , &ds) << 5;
    }
    else/*path monitor mode,DsLatencyMon0 and DsLatencyMon1 for latency*/
    {
        CTC_ERROR_RETURN(_sys_tmm_monitor_get_path_latency_ptr(lchip, p_watermark, &mon_ptr));

        idx1 = (mon_ptr & 0x7FF) >> 3;
        idx2 = mon_ptr & 0x7;
        step = DsLatencyMon0_u_g1_1_latencyMax_f - DsLatencyMon0_u_g1_0_latencyMax_f;

        if (!CTC_IS_BIT_SET(mon_ptr, 11))
        {
            cmd = DRV_IOR(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
            p_watermark->u.latency.max_latency = GetDsLatencyMon0(V, u_g1_0_latencyMax_f + step * idx2, &ds) << 5;
            p_watermark->u.latency.min_latency = GetDsLatencyMon0(V, u_g1_0_latencyMin_f + step * idx2, &ds) << 5;
        }
        else
        {
            cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
            p_watermark->u.latency.max_latency = GetDsLatencyMon1(V, u_g1_0_latencyMax_f + step * idx2, &ds) << 5;
            p_watermark->u.latency.min_latency = GetDsLatencyMon1(V, u_g1_0_latencyMin_f + step * idx2, &ds) << 5;
        }

        SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mon table = %d, idx1 = %d, idx2 = %d\n", CTC_IS_BIT_SET(mon_ptr, 11), idx1, idx2);
    }

    return CTC_E_NONE;
}


int32
sys_tmm_monitor_clear_path_latency_watermark(uint8 lchip, void* p_watermark, uint16 channel_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint16 mon_ptr = 0;
    uint16 idx1 = 0;
    uint16 idx2 = 0;
    uint8  step = 0;
    ds_t ds;

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_legacyFeatureEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    if (field_value == 1)/*legacy mode,DsLatencyMon0 for cnt,DsLatencyMon1 for latency*/
    {
        cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmd, &ds));
        SetDsLatencyMon1(V, u_g1_0_latencyMax_f , &ds, 0);
        SetDsLatencyMon1(V, u_g1_0_latencyMin_f , &ds, 0x3FF);
        cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel_id, cmd, &ds));
    }
    else/*path monitor mode,DsLatencyMon0 and DsLatencyMon1 for latency*/
    {
        CTC_ERROR_RETURN(_sys_tmm_monitor_get_path_latency_ptr(lchip, p_watermark, &mon_ptr));

        idx1 = (mon_ptr & 0x7FF) >> 3;
        idx2 = mon_ptr & 0x7;
        step = DsLatencyMon0_u_g1_1_latencyMax_f - DsLatencyMon0_u_g1_0_latencyMax_f;

        if (!CTC_IS_BIT_SET(mon_ptr, 11))
        {
            cmd = DRV_IOR(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
            SetDsLatencyMon0(V, u_g1_0_latencyMax_f + step * idx2, &ds, 0);
            SetDsLatencyMon0(V, u_g1_0_latencyMin_f + step * idx2, &ds, 0x3FF);
            cmd = DRV_IOW(DsLatencyMon0_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
        }
        else
        {
            cmd = DRV_IOR(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
            SetDsLatencyMon1(V, u_g1_0_latencyMax_f + step * idx2, &ds, 0);
            SetDsLatencyMon1(V, u_g1_0_latencyMin_f + step * idx2, &ds, 0x3FF);
            cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &ds));
        }

        SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mon table = %d, idx1 = %d, idx2 = %d\n", CTC_IS_BIT_SET(mon_ptr, 11), idx1, idx2);
    }
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_set_global_config(uint8 lchip, void* p_mon_cfg)
{
    uint32 cmd = 0;
    uint16 index1 = 0;
    uint32 max_size = 0;
    uint32 value = 0;
    uint32 value1 = 0;
    uint32 legacy_mode = 0;
    uint8 step = 0;
    ds_t ds;
    IrmMiscCtl_m irm_misc_ctl;
    IrmResrcMonState_m irm_resrc_state;
    ErmResrcMonState_m erm_resrc_state;
    ErmMiscCtl_m erm_misc_ctl;
    DsLatencyMon0_m latency_mon;
    ctc_monitor_glb_cfg_t* p_cfg = (ctc_monitor_glb_cfg_t*)p_mon_cfg;

    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&irm_misc_ctl, 0, sizeof(IrmMiscCtl_m));
    sal_memset(&erm_misc_ctl, 0, sizeof(ErmMiscCtl_m));
    sal_memset(&latency_mon, 0, sizeof(DsLatencyMon0_m));

    switch(p_cfg->cfg_type)
    {
    case CTC_MONITOR_GLB_CONFIG_LANTENCY_MODE:
        CTC_MAX_VALUE_CHECK(p_cfg->u.value, CTC_MONITOR_LATENCY_MODE_MAX - 1);
        if(DRV_FROM_AT(lchip) && p_cfg->u.value == CTC_MONITOR_LATENCY_MODE_4)
        {
            return CTC_E_NOT_SUPPORT;
        }
        if (CTC_MONITOR_LATENCY_MODE_0 == p_cfg->u.value)
        {
            legacy_mode = 1;
            cmd = DRV_IOR(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetEpePktProcPathMonCtl(V, legacyFeatureEn_f, &ds, 1);
            SetEpePktProcPathMonCtl(V, latencyMon0Mode_f, &ds, 0);
            cmd = DRV_IOW(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
        else
        {
            legacy_mode = 0;
            cmd = DRV_IOR(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetEpePktProcPathMonCtl(V, legacyFeatureEn_f, &ds, 0);
            SetEpePktProcPathMonCtl(V, latencyMon0Mode_f, &ds, 1);
            SetEpePktProcPathMonCtl(V, pathMonMode_f, &ds, p_cfg->u.value);
            cmd = DRV_IOW(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
        /*clear port viewid map*/
        sal_memset(&ds, 0, sizeof(ds_t));
        sys_usw_ftm_query_table_entry_num(lchip, DsPathViewSrcMap_t, &max_size);
        for (index1 = 0; index1 < max_size; index1++)
        {
            cmd = DRV_IOW(DsPathViewSrcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index1, cmd, &ds));
        }

        sys_usw_ftm_query_table_entry_num(lchip, DsPathViewDstMap_t, &max_size);
        for (index1 = 0; index1 < max_size; index1++)
        {
            cmd = DRV_IOW(DsPathViewDstMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index1, cmd, &ds));
        }

        /*clear db*/
        sal_memset(&p_usw_monitor_master[lchip]->port_array, 0, sizeof(sys_monitor_port_t) * 2 * SYS_MONITOR_MAX_VIEWID);

        /*clear hash tbl*/
        ctc_hash_traverse_remove(p_usw_monitor_master[lchip]->p_monitor_hash, (hash_traversal_fn)_sys_tmm_monitor_free_node_data, NULL);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_MASTER, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_MONITOR, SYS_WB_APPID_MONITOR_SUBID_PATH_LATENCY, 1);
        /*clear DsLatencyMon0/DsLatencyMon1*/
        sal_memset(&ds, 0, sizeof(ds_t));
        step = DsLatencyMon0_u_g1_1_latencyMin_f - DsLatencyMon0_u_g1_0_latencyMin_f;
        for (index1 = 0; index1 < (MCHIP_CAP(SYS_CAP_MONITOR_LATENCY_MAX_LEVEL) + 1); index1++)
        {
            SetDsLatencyMon1(V, u_g1_0_latencyMax_f + step * index1, &ds, 0);
            SetDsLatencyMon1(V, u_g1_0_latencyMin_f + step * index1, &ds, 0x3FF);
        }
        sys_usw_ftm_query_table_entry_num(lchip, DsLatencyMon0_t, &max_size);
        for (index1 = 0; index1 < max_size; index1++)
        {
            if (legacy_mode)
            {
                cmd = DRV_IOW(DsLatencyMon0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index1, cmd, &latency_mon));
            }
            else
            {
                cmd = DRV_IOW(DsLatencyMon0_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index1, cmd, &ds));
            }
            cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index1, cmd, &ds));
        }
        break;
    case CTC_MONITOR_GLB_CONFIG_BUFFER_SNAPSHOT_EN:
        value = p_cfg->u.value ? 1 : 0;
        if(DRV_FROM_AT(lchip))
        {
            value1 = 0x3FFFF;
            cmd = DRV_IOR(IrmResrcMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetIrmResrcMonCtl(V, trigger_c2cCnt_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_criticalCnt_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_scCnt0_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_scCnt1_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_scCnt2_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_scCnt3_f, &ds, value1);
            SetIrmResrcMonCtl(V, trigger_totalCnt_f, &ds, value1);
            cmd = DRV_IOW(ErmResrcMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            cmd = DRV_IOW(IrmResrcMonCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            sal_memset(&ds, 0, sizeof(ds));
            SetIrmResrcMonHeadroomCtl(V, trigger_headroomCnt_f, &ds, value1);
            cmd = DRV_IOW(IrmResrcMonHeadroomCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            cmd = DRV_IOR(IrmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_resrc_state));
            SetIrmResrcMonState(V, resrcShadowLock_f, &irm_resrc_state, value);
            cmd = DRV_IOW(IrmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_resrc_state));

            cmd = DRV_IOR(ErmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_resrc_state));
            SetErmResrcMonState(V, resrcShadowLock_f, &erm_resrc_state, value);
            cmd = DRV_IOW(ErmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_resrc_state));
        }
        else
        {
            cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_misc_ctl));
            SetIrmMiscCtl(V, c2cCntLockEn_f, &irm_misc_ctl, value);
            SetIrmMiscCtl(V, criticalCntLockEn_f, &irm_misc_ctl, value);
            cmd = DRV_IOW(IrmMiscCtl_t, DRV_ENTRY_FLAG);
            SYS_SET_TBL_ALL_DP(lchip, cmd, irm_misc_ctl);
            /*need disable aqm scan,and queue lock need wait for moment for bug 118503*/
            value1 = p_cfg->u.value ? 0 : 1;
            cmd = DRV_IOW(ErmAqmQueueScanCtl_t, ErmAqmQueueScanCtl_aqmQueueScanEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value1));
            cmd = DRV_IOW(ErmAqmPortScanCtl_t, ErmAqmPortScanCtl_aqmPortScanEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value1));
            cmd = DRV_IOW(ErmMiscCtl_t, ErmMiscCtl_glbAqmPortDis_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            sal_task_sleep(200);
            cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
            SetErmMiscCtl(V, c2cCntLockEn_f, &erm_misc_ctl, value);
            SetErmMiscCtl(V, criticalCntLockEn_f, &erm_misc_ctl, value);
            SetErmMiscCtl(V, portCntLockEn_f, &erm_misc_ctl, value);
            SetErmMiscCtl(V, queueCntLockEn_f, &erm_misc_ctl, value);
            SetErmMiscCtl(V, aqmQueueUseAvgDis_f, &erm_misc_ctl, value);
            cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}


int32
sys_tmm_monitor_get_global_config(uint8 lchip, void* p_mon_cfg)
{
    uint32 cmd = 0;
    uint32 value = 0;
    ctc_monitor_glb_cfg_t* p_cfg = (ctc_monitor_glb_cfg_t*)p_mon_cfg;

    switch(p_cfg->cfg_type)
    {
    case CTC_MONITOR_GLB_CONFIG_LANTENCY_MODE:
        cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_legacyFeatureEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        if (value)
        {
            p_cfg->u.value = CTC_MONITOR_LATENCY_MODE_0;
        }
        else
        {
            cmd = DRV_IOR(EpePktProcPathMonCtl_t, EpePktProcPathMonCtl_pathMonMode_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            p_cfg->u.value = value;
        }

        break;
    case CTC_MONITOR_GLB_CONFIG_BUFFER_SNAPSHOT_EN:
        if(DRV_FROM_AT(lchip))
        {
            IrmResrcMonState_m resrc_state;
            cmd = DRV_IOR(IrmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &resrc_state));
            value = GetIrmResrcMonState(V, resrcShadowLock_f, &resrc_state);

            cmd = DRV_IOR(ErmResrcMonState_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &resrc_state));
            value = value || GetIrmResrcMonState(V, resrcShadowLock_f, &resrc_state);
        }
        else
        {
            cmd = DRV_IOR(IrmMiscCtl_t, IrmMiscCtl_c2cCntLockEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        }
        p_cfg->u.value = value;
        break;
    default:
        return CTC_E_INVALID_PARAM;

    }

    return CTC_E_NONE;
}

int32
sys_tmm_monitor_sync_latency(uint8 lchip, ctc_monitor_data_t *p_data,
                                     void* p_latency_param, uint64* p_ts)
{
     uint8 info_type = 0;
     uint16 channel_id = 0;
     uint8 idx = 0;
     uint8 gchip = 0;
     uint16 lport = 0;
     uint32 gport = 0;
     uint8 msg_idx = 0;
     ctc_monitor_msg_t *p_msg = NULL;
     ms_latency_mon_tmm_t *p_latency = (ms_latency_mon_tmm_t *)p_latency_param;

     msg_idx = p_data->msg_num;
     p_msg =  (ctc_monitor_msg_t*)p_data->p_msg +msg_idx;
     p_msg->monitor_type = CTC_MONITOR_LATENCY;
     p_msg->timestamp = *p_ts;
     CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
     p_msg->gchip = gchip;
     channel_id = p_latency->u.event.channelId;
     /*Need mapping from channel to lport*/
     lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
     sys_usw_get_gchip_id(lchip, &gchip);
     gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

     info_type = p_latency->u.event.infoType;

     if (0 == info_type)
     {
         p_msg->msg_type = CTC_MONITOR_MSG_STATS;
         p_msg->u.latency_stats.gport = gport;
         p_msg->u.latency_stats.threshold_cnt[0] = p_latency->u.mon.latencyThrdCnt0_31_23 << 23 | p_latency->u.mon.latencyThrdCnt0_22_0;
         p_msg->u.latency_stats.threshold_cnt[1] = p_latency->u.mon.latencyThrdCnt1_31_23 << 23 | p_latency->u.mon.latencyThrdCnt1_22_0;
         p_msg->u.latency_stats.threshold_cnt[2] = p_latency->u.mon.latencyThrdCnt2_31_23 << 23 | p_latency->u.mon.latencyThrdCnt2_22_0;
         p_msg->u.latency_stats.threshold_cnt[3] = p_latency->u.mon.latencyThrdCnt3_31_23 << 23 | p_latency->u.mon.latencyThrdCnt3_22_0;
         p_msg->u.latency_stats.threshold_cnt[4] = p_latency->u.mon.latencyThrdCnt4_31_23 << 23 | p_latency->u.mon.latencyThrdCnt4_22_0;
         p_msg->u.latency_stats.threshold_cnt[5] = p_latency->u.mon.latencyThrdCnt5_31_23 << 23 | p_latency->u.mon.latencyThrdCnt5_22_0;
         p_msg->u.latency_stats.threshold_cnt[6] = p_latency->u.mon.latencyThrdCnt6_31_23 << 23 | p_latency->u.mon.latencyThrdCnt6_22_0;
         p_msg->u.latency_stats.threshold_cnt[7] = p_latency->u.mon.latencyThrdCnt7_31_23 << 23 | p_latency->u.mon.latencyThrdCnt7_22_0;

         for (idx = 0; idx < 8; idx++)
         {
             p_usw_monitor_master[lchip]->latency_stats[channel_id][idx] += p_msg->u.latency_stats.threshold_cnt[idx];
         }
     }
     else
     {
         p_msg->msg_type = CTC_MONITOR_MSG_EVENT;
         p_msg->u.latency_event.gport = gport;
         p_msg->u.latency_event.event_state = p_latency->u.event.valid;
         p_msg->u.latency_event.source_port = SYS_MAP_DRV_GPORT_TO_CTC_GPORT(p_latency->u.event.sourcePort);
         p_msg->u.latency_event.port = p_latency->u.event.localPhyPort;
         p_msg->u.latency_event.level = p_latency->u.event.region;
         p_msg->u.latency_event.event_state = (p_msg->u.latency_event.event_state == 1) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
         p_msg->u.latency_event.latency = ((uint64)p_latency->u.event.residenceTime_47_43 << 43) | ((uint64)p_latency->u.event.residenceTime_42_11 << 11) | p_latency->u.event.residenceTime_10_0;
         p_msg->timestamp = ((uint64)p_latency->u.event.timestamp_63_43 << 43) | ((uint64)p_latency->u.event.timestamp_42_11 << 11) | p_latency->u.event.timestamp_10_0;
     }

     msg_idx++;
     p_data->msg_num = msg_idx;
    return CTC_E_NONE;
}
 
STATIC int32
_sys_tmm_monitor_get_port_by_queue_id(uint8 lchip, uint16 queue_id, uint16* lport)
{
    DsQMgrGrpParentSelect_m  que_grp_parent;
    uint32 table_id[CTC_QOS_SCHED_GROUP_LVL_MAX] = {DsQMgrL0ParentSelect_t, DsQMgrL1ParentSelect_t, DsQMgrL2ParentSelect_t, DsQMgrL3ParentSelect_t};
    uint32 field_id[CTC_QOS_SCHED_GROUP_LVL_MAX] = {DsQMgrL0ParentSelect_parentId_f, DsQMgrL1ParentSelect_parentId_f, DsQMgrL2ParentSelect_parentId_f,
                                                  DsQMgrL3ParentSelect_parentId_f};
    uint32 field_val  = 0;
    uint32 sub_grp_id = 0;
    uint32 chip_lport = 0;
    uint32 channel    = 0;
    uint32 cmd = 0;
    uint8  lvl = 0;

    if (queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_CTL))
    {
        channel = (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_CTL)) / MCHIP_CAP(SYS_CAP_QOS_CTL_QUEUE_NUM);
    }
    else if((queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP)) && (queue_id < (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP) + MCHIP_CAP(SYS_CAP_REASON_TOTAL_QUEUE_NUM))))
    {
        channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);
    }
    else
    {
        sub_grp_id = CTC_IS_BIT_SET(queue_id, 13) ? ((queue_id & 0x2000) >> 3) + ((queue_id & 0x1FFF) >> 4) : queue_id >> 3;
        cmd = DRV_IOR(DsQMgrGrpParentSelect_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, sub_grp_id, cmd, &que_grp_parent));
        sub_grp_id = GetDsQMgrGrpParentSelect(V, parentId_f, &que_grp_parent);
        if (GetDsQMgrGrpParentSelect(V, linkToPortEn_f, &que_grp_parent))
        {
            channel = sub_grp_id;
        }
        else
        {
            for (lvl = CTC_QOS_SCHED_GROUP_LVL_3 + 1; lvl > CTC_QOS_SCHED_GROUP_LVL_R; lvl--)
            {
                cmd = DRV_IOR(table_id[lvl - 1], field_id[lvl - 1]);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sub_grp_id, cmd, &sub_grp_id));
                if (0 == sub_grp_id && CTC_QOS_SCHED_GROUP_LVL_R != (lvl - 1))
                {
                    return CTC_E_NOT_EXIST;
                }
            }
            channel = sub_grp_id;
        }
    }
    cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &chip_lport));

    cmd = DRV_IOR(DsQWriteDestPortChannelMap_t, DsQWriteDestPortChannelMap_channelId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chip_lport, cmd, &field_val));

    if (field_val != channel)
    {
        return CTC_E_NOT_EXIST;
    }
    *lport = chip_lport;
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_sync_buffer(uint8 lchip, ctc_monitor_data_t *p_data,
                                   void* p_buffer_param, uint64* p_ts, uint8 msg_type, uint8 dir, uint8 dp)
{
    uint8 info_type = 0;
    uint16 channel_id = 0;
    uint8 gchip = 0;
    uint16 lport = 0;
    uint32 gport = 0;
    uint8 msg_idx = 0;
    ctc_monitor_msg_t *p_msg = NULL;
    uint32 sc_cnt[SYS_MONITOR_SC_NUM_MAX] = {0};
    uint32 field_val = 0;
    uint32 buffer_cnt = 0;
    uint8 burst_type = 0;
    uint8 level = 0;
    uint8 idx = 0;
    uint64 timestamp = 0;

    msg_idx = p_data->msg_num;
    p_msg = (ctc_monitor_msg_t*)p_data->p_msg +msg_idx;
    p_msg->monitor_type = CTC_MONITOR_BUFFER;
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    p_msg->gchip = gchip;

    if(dir == CTC_EGRESS)
    {
        if(msg_type == CTC_MONITOR_MSG_STATS)
        {
            temp_erm_resrc_mon_info_tmm_t *p_buffer = (temp_erm_resrc_mon_info_tmm_t *)p_buffer_param;
            info_type = p_buffer->u.g1.monInfoType;
            p_msg->u.buffer_stats.dir = CTC_EGRESS;
            if (0 == info_type)
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                p_msg->timestamp = *p_ts;
                channel_id = p_buffer->u.g1.channelId;

                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                sys_usw_get_gchip_id(lchip, &gchip);
                gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

                p_msg->u.buffer_stats.gport = gport;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT;
                p_msg->u.buffer_stats.buffer_cnt  = p_buffer->u.g1.pktBufCnt;

                p_usw_monitor_master[lchip]->buffer_stats[channel_id][0] = p_buffer->u.g1.ucastBufCnt_16_12 << 12 | p_buffer->u.g1.ucastBufCnt_11_0;
                p_usw_monitor_master[lchip]->buffer_stats[channel_id][1] = p_buffer->u.g1.mcastBufCnt;

                msg_idx++;
            }
            else if(1 == info_type)
            {
                sc_cnt[0] = p_buffer->u.g2.scCnt_0_16_0;
                sc_cnt[1] = p_buffer->u.g2.scCnt_1_16_12 << 12 | p_buffer->u.g2.scCnt_1_11_0;
                sc_cnt[2] = p_buffer->u.g2.scCnt_2_16_0;
                sc_cnt[3] = p_buffer->u.g2.scCnt_3_16_10 << 10 | p_buffer->u.g2.scCnt_3_9_0;
                for (idx = 0; idx < SYS_MONITOR_SC_NUM_MAX; idx++)
                {
                    p_msg = (ctc_monitor_msg_t*)p_data->p_msg + msg_idx;
                    p_msg->gchip = gchip;
                    p_msg->monitor_type = CTC_MONITOR_BUFFER;
                    p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                    p_msg->u.buffer_stats.sc  = idx;
                    p_msg->u.buffer_stats.dir = CTC_EGRESS;
                    p_msg->u.buffer_stats.buffer_cnt  = sc_cnt[idx];
                    p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_SC;
                    msg_idx++;
                }
            }
            else if(2 == info_type)
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.g3.totalCnt;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_TOTAL;
                p_usw_monitor_master[lchip]->total_stats = p_msg->u.buffer_stats.buffer_cnt;
                msg_idx++;
            }
            else if(3 == info_type)
            {
                /*tmm do nothing*/
            }
            else if(4 == info_type)/*TMM port sc*/
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;

                channel_id = p_buffer->u.g5.channelId;

                /*Need mapping from channel to lport*/
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                sys_usw_get_gchip_id(lchip, &gchip);
                gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

                p_msg->u.buffer_stats.gport = gport;
                p_msg->u.buffer_stats.sc = p_buffer->u.g5.sc;
                p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.g5.pktBufCnt;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT_SC;
                msg_idx++;
            }
            else if(5 == info_type)/*TMM*/
            {
                if (CTC_E_NONE != _sys_tmm_monitor_get_port_by_queue_id(lchip, p_buffer->u.g6.queueId, &lport))
                {
                    return CTC_E_NONE;
                }
                p_msg->u.buffer_stats.queue_id.gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                p_msg->u.buffer_stats.queue_id.queue_id = p_buffer->u.g6.queueId;
                p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.g6.queueCnt_16_15 << 15 | p_buffer->u.g6.queueCnt_14_0;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_QUEUE;
                msg_idx++;
            }
        }
        else if(msg_type == CTC_MONITOR_MSG_EVENT)
        {
            temp_erm_mb_mon_info_tmm_t *p_buffer = (temp_erm_mb_mon_info_tmm_t *)p_buffer_param;
            p_msg->msg_type = CTC_MONITOR_MSG_EVENT;
            p_msg->timestamp = *p_ts;
            burst_type = p_buffer->microburstType;
            switch(burst_type)
            {
            case 1:
                channel_id = (p_buffer->u_data >> 4) & 0xFF;
                /*Need mapping from channel to lport*/
                lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id);
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(lport);
                sys_usw_get_gchip_id(lchip, &gchip);
                gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

                p_msg->u.buffer_event.gport = gport;
                p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_PORT;
                p_msg->u.buffer_event.uc_cnt            =  p_buffer->u.channel.ucastBufCnt;
                p_msg->u.buffer_event.mc_cnt            =  (p_buffer->u_data & 0x3) << 15 | p_buffer->u.channel.mcastBufCnt_14_0;

                field_val = p_usw_monitor_master[lchip]->mb_thrd->port_thrd[channel_id][1];
                buffer_cnt = p_msg->u.buffer_event.uc_cnt + p_msg->u.buffer_event.mc_cnt;
                break;
             case 2:
                p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_TOTAL;
                p_msg->u.buffer_event.buffer_cnt = p_buffer->u.total.totalCnt;
                field_val = p_usw_monitor_master[lchip]->mb_thrd->total_thrd[1];
                buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
                break;
             case 3:
                p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_SC;
                p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.sc.scCnt;
                p_msg->u.buffer_event.sc = p_buffer->u.sc.id;
                field_val = p_usw_monitor_master[lchip]->mb_thrd->sc_thrd[p_buffer->u.sc.id][1];
                buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
                break;
             case 4:
                p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_CONTROL;
                p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.critical.criticalCnt;
                field_val = p_usw_monitor_master[lchip]->mb_thrd->critical_thrd[1];
                buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
                break;
             case 5:
                p_msg->u.buffer_event.buffer_type = CTC_MONITOR_BUFFER_C2C;
                p_msg->u.buffer_event.buffer_cnt =  p_buffer->u.c2c.c2cCnt;
                field_val = p_usw_monitor_master[lchip]->mb_thrd->c2c_thrd[1];
                buffer_cnt = p_msg->u.buffer_event.buffer_cnt;
                break;
            }

            p_msg->u.buffer_event.event_state = (buffer_cnt >= field_val) ? CTC_MONITOR_EVENT_STATE_OCCUR:CTC_MONITOR_EVENT_STATE_CLEAR;
            msg_idx++;

            if(p_msg->u.buffer_event.event_state == CTC_MONITOR_EVENT_STATE_OCCUR && p_msg->u.buffer_event.buffer_type == CTC_MONITOR_BUFFER_PORT)
            {
                p_usw_monitor_master[lchip]->mburst_timestamp[channel_id] = p_msg->timestamp;
            }
            else if(p_msg->u.buffer_event.event_state == CTC_MONITOR_EVENT_STATE_CLEAR && p_msg->u.buffer_event.buffer_type == CTC_MONITOR_BUFFER_PORT)
            {
                timestamp = p_msg->timestamp - p_usw_monitor_master[lchip]->mburst_timestamp[channel_id];
                _sys_usw_monitor_get_mburst_level(lchip, &level, timestamp);
                if(level != 0xff)
                {
                    p_msg = (ctc_monitor_msg_t*)p_data->p_msg +msg_idx;
                    p_msg->monitor_type = CTC_MONITOR_BUFFER;
                    p_msg->msg_type = CTC_MONITOR_MSG_MBURST_STATS;
                    p_msg->gchip = gchip;
                    p_msg->timestamp = *p_ts;
                    p_usw_monitor_master[lchip]->mburst_stats[channel_id][level] ++;
                    p_msg->u.mburst_stats.gport = gport;
                    for (idx = 0; idx < 8; idx++)
                    {
                         p_msg->u.mburst_stats.threshold_cnt[idx] = p_usw_monitor_master[lchip]->mburst_stats[channel_id][idx];
                    }
                    msg_idx++;
                }
            }
        }
        p_data->msg_num = msg_idx;
    }
    else if(dir == CTC_INGRESS)
    {
        if(msg_type == CTC_MONITOR_MSG_STATS)
        {
            temp_irm_resrc_mon_info_tmm_t *p_buffer = (temp_irm_resrc_mon_info_tmm_t *)p_buffer_param;
            p_msg->u.buffer_stats.dir = CTC_INGRESS;
            info_type = p_buffer->u.g1.monInfoType;

            if (0 == info_type)
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                p_msg->timestamp = *p_ts;
                channel_id = p_buffer->u.g1.channelId;

                /*Need mapping from channel to lport*/
                channel_id = dp ? channel_id + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) : channel_id;
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                sys_usw_get_gchip_id(lchip, &gchip);
                gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

                p_msg->u.buffer_stats.gport = gport;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT;
                p_msg->u.buffer_stats.buffer_cnt  = p_buffer->u.g1.pktBufCnt;
                msg_idx++;
            }
            else if(1 == info_type)
            {
                sc_cnt[0] = p_buffer->u.g2.scCnt_0_16_0;
                sc_cnt[1] = p_buffer->u.g2.scCnt_1_16_12 << 12 | p_buffer->u.g2.scCnt_1_11_0;
                sc_cnt[2] = p_buffer->u.g2.scCnt_2_16_0;
                sc_cnt[3] = p_buffer->u.g2.scCnt_3_16_10 << 10 | p_buffer->u.g2.scCnt_3_9_0;
                for (idx = 0; idx < SYS_MONITOR_SC_NUM_MAX; idx++)
                {
                    p_msg = (ctc_monitor_msg_t*)p_data->p_msg + msg_idx;
                    p_msg->gchip = gchip;
                    p_msg->monitor_type = CTC_MONITOR_BUFFER;
                    p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                    p_msg->u.buffer_stats.sc  = idx;
                    p_msg->u.buffer_stats.dir = CTC_INGRESS;
                    p_msg->u.buffer_stats.buffer_cnt  = sc_cnt[idx];
                    p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_SC;
                    msg_idx++;
                }
            }
            else if(2 == info_type)
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.g3.totalCnt;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_TOTAL;
                msg_idx++;
            }
            else if(4 == info_type)/*TMM port sc*/
            {
                p_msg->msg_type = CTC_MONITOR_MSG_STATS;
                channel_id = p_buffer->u.g5.channelId;

                /*Need mapping from channel to lport*/
                channel_id = dp ? channel_id + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) : channel_id;
                lport = SYS_MAP_SYS_LPORT_TO_DRV_LPORT(SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel_id));
                sys_usw_get_gchip_id(lchip, &gchip);
                gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

                p_msg->u.buffer_stats.gport = gport;
                p_msg->u.buffer_stats.sc = p_buffer->u.g5.mappedSc;
                p_msg->u.buffer_stats.buffer_cnt = p_buffer->u.g5.pktBufCnt;
                p_msg->u.buffer_stats.buffer_type = CTC_MONITOR_BUFFER_PORT_SC;
                msg_idx++;
            }
        }
        p_data->msg_num = msg_idx;
    }
    return CTC_E_NONE;
}


int32
sys_tmm_monitor_buf_sync_data(uint8 lchip, void* p_data)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    uint8* p_monitor = NULL;
    sys_dma_info_t* p_dma_info = (sys_dma_info_t*)p_data;
    ctc_monitor_data_t  monitor_data;
    cpu_info_tmm_t* p_cpu_info = NULL;
    ms_irm_mon_tmm_t* p_irm_mon = NULL;
    ms_erm_mon_tmm_t* p_erm_mon = NULL;
    ds_t ds;
    uint64 ts;
    uint8 dp = 0;

    sal_memset(&monitor_data, 0, sizeof(monitor_data));

    monitor_data.p_msg = p_usw_monitor_master[lchip]->p_buffer;
    entry_num = p_dma_info->entry_num;
    p_monitor = ((uint8*)p_dma_info->p_data);

    for (index = 0; index < entry_num; index++)
    {
        p_cpu_info = (cpu_info_tmm_t*)p_monitor;
        ts = (uint64)p_cpu_info->timestamp_63_32 << 32 | p_cpu_info->timestamp_31_0;
        dp = p_cpu_info->infoSource;
        if (p_cpu_info->infoType == SYS_MONITOR_TYPE_ERM)/* ERM */
        {
            p_erm_mon = (ms_erm_mon_tmm_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);
            /*buffer stats*/
            if (!p_erm_mon->infoType)
            {
                sal_memset(&ds, 0, sizeof(ds));
                ds[0] = (p_erm_mon->u_62_31  & 0x1) << 31 | p_erm_mon->u_30_0;
                ds[1] = (p_erm_mon->u_94_63  & 0x1) << 31 | p_erm_mon->u_62_31 >> 1;
                ds[2] = (p_erm_mon->u_126_95 & 0x1) << 31 | p_erm_mon->u_94_63 >> 1;
                sys_tmm_monitor_sync_buffer(lchip, &monitor_data, (void*)&ds, &ts, CTC_MONITOR_MSG_STATS, CTC_EGRESS, 0);
            }
            else/*buffer event*/
            {
                sal_memset(&ds, 0, sizeof(ds));

                if ((p_erm_mon->u_62_31 >> 16) & 0x1)/*enqueue*/
                {
                    ds[0] = (p_erm_mon->u_62_31 & 0x1) << 31 | p_erm_mon->u_30_0;
                    ds[1] = (p_erm_mon->u_62_31 >> 1) & 0x7FFF;
                    sys_tmm_monitor_sync_buffer(lchip, &monitor_data, (void*)&ds, &ts, CTC_MONITOR_MSG_EVENT, CTC_EGRESS, 0);
                }

                if (p_erm_mon->u_126_95 & 0x1)/*dequeue*/
                {
                    ds[0] = (p_erm_mon->u_94_63 & 0x1FFFF) << 15 | p_erm_mon->u_62_31 >> 17 ;
                    ds[1] = (p_erm_mon->u_94_63 >> 17) & 0x7FFF;
                    sys_tmm_monitor_sync_buffer(lchip, &monitor_data, (void*)&ds, &ts, CTC_MONITOR_MSG_EVENT, CTC_EGRESS, 0);
                }
            }

            p_monitor += sizeof(CpuInfoErmMon_m);
        }
        else if (p_cpu_info->infoType == SYS_MONITOR_TYPE_IRM)/* IRM */
        {
            p_irm_mon = (ms_irm_mon_tmm_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);
            /*buffer stats*/
            if (!p_irm_mon->infoType)
            {
                sal_memset(&ds, 0, sizeof(ds));
                ds[0] = (p_irm_mon->u_62_31  & 0x1) << 31 | p_irm_mon->u_30_0;
                ds[1] = (p_irm_mon->u_94_63  & 0x1) << 31 | p_irm_mon->u_62_31 >> 1;
                ds[2] = (p_irm_mon->u_94_63  >> 1) & 0x7F;
                sys_tmm_monitor_sync_buffer(lchip, &monitor_data, (void*)&ds, &ts, CTC_MONITOR_MSG_STATS, CTC_INGRESS, dp);
            }

            p_monitor += sizeof(CpuInfoIrmMon_m);
        }

        /*CallBack*/
        if (monitor_data.msg_num >= MCHIP_CAP(SYS_CAP_MONITOR_SYNC_CNT))
        {
            if (p_usw_monitor_master[lchip]->func)
            {
                p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
            }
            monitor_data.p_msg = p_usw_monitor_master[lchip]->p_buffer;
            monitor_data.msg_num = 0;
        }
    }

    /*CallBack*/
    if (p_usw_monitor_master[lchip]->func && monitor_data.msg_num != 0)
    {
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
    }

    return CTC_E_NONE;
}

int32
sys_tmm_monitor_latency_sync_data(uint8 lchip, void* p_data)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    uint8* p_monitor = NULL;
    sys_dma_info_t* p_dma_info = (sys_dma_info_t*)p_data;
    ctc_monitor_data_t  monitor_data;
    cpu_info_tmm_t* p_cpu_info = NULL;
    ms_latency_mon_tmm_t* p_latency_mon = NULL;
    uint64 ts;

    sal_memset(&monitor_data, 0, sizeof(monitor_data));

    monitor_data.p_msg = p_usw_monitor_master[lchip]->p_latency;
    entry_num = p_dma_info->entry_num;
    p_monitor = ((uint8*)p_dma_info->p_data);
    for (index = 0; index < entry_num; index++)
    {
        p_cpu_info = (cpu_info_tmm_t*)p_monitor;
        ts = (uint64)p_cpu_info->timestamp_63_32 << 32 | p_cpu_info->timestamp_31_0;

        p_latency_mon = (ms_latency_mon_tmm_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);
        sys_tmm_monitor_sync_latency(lchip, &monitor_data, p_latency_mon, &ts);

        p_monitor += DRV_TABLE_ENTRY_SIZE(lchip, CpuInfoLatencyMon_t);

        /*CallBack*/
        if (monitor_data.msg_num == MCHIP_CAP(SYS_CAP_MONITOR_SYNC_CNT))
        {
            if(p_usw_monitor_master[lchip]->func)
            {
                p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
            }
            monitor_data.p_msg = p_usw_monitor_master[lchip]->p_latency;
            monitor_data.msg_num = 0;
        }

    }
    /*CallBack*/
    if (p_usw_monitor_master[lchip]->func && monitor_data.msg_num != 0)
    {
        p_usw_monitor_master[lchip]->func(&monitor_data, p_usw_monitor_master[lchip]->user_data);
    }

    return CTC_E_NONE;
}

int32
sys_tmm_monitor_efd_sync_data(uint8 lchip, void* p_data)
{
    uint16 entry_num = 0;
    uint16 index = 0;
    uint8* p_monitor = NULL;
    sys_dma_info_t* p_dma_info = (sys_dma_info_t*)p_data;
    ctc_efd_data_t efd_data;
    ms_efd_mon_tmm_t* p_efd_mon = NULL;
    uint32 pp_id = 0;

    sal_memset(&efd_data, 0, sizeof(efd_data));
    entry_num = p_dma_info->entry_num;
    p_monitor = ((uint8*)p_dma_info->p_data);
    for (index = 0; index < entry_num; index++)
    {
        p_efd_mon = (ms_efd_mon_tmm_t*)SYS_USW_DMA_GET_INFO_ADDR(lchip, p_monitor);
        if(DRV_FROM_AT(lchip))
        {
            pp_id = (((*(uint32*)p_monitor >> 24)&0x3) + (p_dma_info->base_lchip));/*per core ppid add core id*/
            efd_data.flow_id_array[efd_data.count++] = ((pp_id << 28) | p_efd_mon->efdMonPtr);
        }
        else
        {
            efd_data.flow_id_array[efd_data.count++] = p_efd_mon->efdMonPtr;
        }
        p_monitor += sizeof(CpuInfoEfdMon_m);

        if(efd_data.count == CTC_EFD_FLOW_ID_ARRAY_MAX)
        {
            /* process efd callback */
            sys_usw_efd_sync_data(lchip, &efd_data);
            efd_data.count = 0;
        }
    }

    if(efd_data.count != 0)
    {
        /* process efd callback */
        sys_usw_efd_sync_data(lchip, &efd_data);
    }
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 max_size = 0;
    uint32 hash_size = 0;
    uint16 index;
    EpePktProcPathMonCtl_m path_mon_ctl;
    EpeHdrProcMiscCtl_m hdr_proc_misc_ctl;
    DsLatencyMon1_m DsLatencyMon1;

    sal_memset(&path_mon_ctl, 0 , sizeof(EpePktProcPathMonCtl_m));
    sal_memset(&DsLatencyMon1, 0 , sizeof(DsLatencyMon1_m));

    /*TMM*/
    cmd = DRV_IOR(EpeHdrProcMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdr_proc_misc_ctl));
    SetEpeHdrProcMiscCtl(V, latencyMonRdClrEn_f, &hdr_proc_misc_ctl, 0);
    cmd = DRV_IOW(EpeHdrProcMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdr_proc_misc_ctl));

    cmd = DRV_IOR(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &path_mon_ctl));
    SetEpePktProcPathMonCtl(V, prioMode_f, &path_mon_ctl, 0);
    SetEpePktProcPathMonCtl(V, legacyFeatureEn_f, &path_mon_ctl, 1);
    SetEpePktProcPathMonCtl(V, latencyMon0Mode_f, &path_mon_ctl, 0);/*ActMon pkt count mode*/
    SetEpePktProcPathMonCtl(V, latencyMon0PtrMode_f, &path_mon_ctl, 1);
    SetEpePktProcPathMonCtl(V, latencyMon1PtrMode_f, &path_mon_ctl, 0);
    SetEpePktProcPathMonCtl(V, pathMonMode_f, &path_mon_ctl, CTC_MONITOR_LATENCY_MODE_MAX);
    SetEpePktProcPathMonCtl(V, qMgrGrpMode_f, &path_mon_ctl, 0xFF);
    cmd = DRV_IOW(EpePktProcPathMonCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &path_mon_ctl));

    /*init DsLatencyMon1 latencyMin*/
    if (!DRV_FROM_AT(lchip))
    {
        sys_usw_ftm_query_table_entry_num(lchip, DsLatencyMon1_t, &max_size);
        SetDsLatencyMon1(V, u_g1_0_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_1_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_2_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_3_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_4_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_5_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_6_latencyMin_f, &DsLatencyMon1, 0x3FF);
        SetDsLatencyMon1(V, u_g1_7_latencyMin_f, &DsLatencyMon1, 0x3FF);
        cmd = DRV_IOW(DsLatencyMon1_t, DRV_ENTRY_FLAG);
        for (index = 0; index < max_size; index++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &DsLatencyMon1));
        }
    }

#ifdef ARCTIC
    if (DRV_FROM_AT(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_BUFFER_MON, sys_at_monitor_buf_sync_data));
        CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_LATENCY_MON, sys_at_monitor_latency_sync_data));
        CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_BUFFER_MON_SCAN, sys_at_monitor_sync_buffer_stats));
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_BSR_IRM_MON , sys_at_monitor_snapshot_state_isr));
        CTC_ERROR_RETURN(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_BSR_ERM_MON , sys_at_monitor_snapshot_state_isr));
    }
    else
#endif
    {
        CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_BUFFER_MON, sys_tmm_monitor_buf_sync_data));
        CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_LATENCY_MON, sys_tmm_monitor_latency_sync_data));
    }
    CTC_ERROR_RETURN(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_EFD_MON, sys_tmm_monitor_efd_sync_data));
    hash_size = SYS_MONITOR_MAX_VIEWID * SYS_MONITOR_MAX_VIEWID / SYS_HASH_SIZE_COMPRESS_RATE_8;
    p_usw_monitor_master[lchip]->p_monitor_hash = ctc_hash_create(
                                                        hash_size/CTC_HASH_32_BLOCK_SIZE,
                                                        CTC_HASH_32_BLOCK_SIZE,
                                                        (hash_key_fn)_sys_tmm_monitor_hash_make,
                                                        (hash_cmp_fn)_sys_tmm_monitor_hash_cmp);
    if (NULL == p_usw_monitor_master[lchip]->p_monitor_hash)
    {
        SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "No Memory\n");
        return CTC_E_NO_MEMORY;
    }
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_deinit(uint8 lchip)
{
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_BUFFER_MON, NULL);
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_LATENCY_MON, NULL);
    sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_EFD_MON, NULL);
    ctc_hash_free2(p_usw_monitor_master[lchip]->p_monitor_hash, (hash_traversal_fn)_sys_tmm_monitor_free_node_data, NULL);
    return CTC_E_NONE;
}

int32
sys_tmm_monitor_show_path(uint8 lchip)
{
    uint8 gchip = 0;
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip,&gchip));
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------\n");
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "Latency path:\n");
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------\n");
    SYS_MONITOR_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-10s  %-10s\n", "src-gport", "dst-gport");
    ctc_hash_traverse(p_usw_monitor_master[lchip]->p_monitor_hash,
                      (hash_traversal_fn)_sys_tmm_monitor_dump_hash_node, &gchip);

    return CTC_E_NONE;
}

#endif

#endif

